#ifndef JFILEDEVICE_H
#define JFILEDEVICE_H

#include <JXQIO/JAbstractIO>

namespace JXQ
{

class JDebug;
class JFileDevicePrivate;

class JXQLIB_EXPORT JFileDevice : public JAbstractIO
{
protected:
	JFileDevice();
	explicit JFileDevice(const JString &name);
	~JFileDevice();

public:
	bool open(OpenMode mode) override;
	virtual bool open(int handle, OpenMode mode);
	virtual bool open(const FILE *fsp, OpenMode mode);
	bool close() override;

public:
	JString readLine() override;

public:
	int64_t ioctl(unsigned int cmd, void * = nullptr) override;
	void flush() override;

public:
	int64_t bytesAvailable() const override;
	int64_t seek(SeekWhence whence, int64_t offset) override;
	int64_t tell() const override;
	int64_t size() const override;

public:
	void setName(const JString &name);
	JString name() const;
	void setAutoCloseHandle(bool enable = true);
	bool autoCloseHandle() const;
	bool isExist() const;
	static bool isExist(const JString &name);

public:
	JHandle handle() const;
	FILE *stdStreamPointer() const;

protected:
	int64_t virtualRead(int64_t bufSize, void *buffer) override;
	int64_t virtualWrite(int64_t bufSize, const void *buffer) override;

private:
	J_DECLARE_PRIVATE(JFileDevice)
	J_DISABLE_COPY(JFileDevice)

private:
	friend JDebug &operator<<(JDebug &d, const JFileDevice *fileDev);
	friend JDebug &operator<<(JDebug &&d, const JFileDevice *fileDev);
	friend JDebug &operator<<(JDebug &d, const JFileDevice &fileDev);
	friend JDebug &operator<<(JDebug &&d, const JFileDevice &fileDev);
};

} //namespace JXQ


#endif //JFILEDEVICE_H
